package mainmodel

import (
	"encoding/gob"
	"sort"
	"strconv"
	"sync"
	"web_server/model"
)

type MenuL2 struct {
	Title string
	Url   string
}
type MenuL1 struct {
	Title   string
	Icon    string
	Submenu []MenuL2
}

var roleMenu map[int64][]MenuL1 = make(map[int64][]MenuL1)
var roleMenuMut sync.RWMutex

func init() {
	gob.Register(UserModel{})
}

func GetRoleMenu(role int64) []MenuL1 {
	roleMenuMut.RLock()
	if v, ok := roleMenu[role]; ok {
		roleMenuMut.RUnlock()
		return v
	}
	roleMenuMut.RUnlock()
	roleMenuMut.Lock()
	defer roleMenuMut.Unlock()
	if v, ok := roleMenu[role]; ok {
		return v
	}
	menu := getMenuList(getMenuMap(role))
	roleMenu[role] = menu
	return menu

	// menu := getMenuList(getMenuMap(role))
	// return menu
}

func ClearRoleMenu() {
	roleMenuMut.Lock()
	defer roleMenuMut.Unlock()
	roleMenu = make(map[int64][]MenuL1)
}

func getMenuMap(role int64) (menumap map[int64]*MenuL1) {
	menumap = make(map[int64]*MenuL1)

	var menuids []int64
	if err := model.DBSlaveRand().Select(&menuids, "SELECT menu_id FROM t_base_role_menu WHERE role_id = ?", role); err != nil {
		panic(err)
	} else if len(menuids) == 0 {
		return
	}
	var menuinfo []struct {
		Id          int64
		Parent_id   int64
		Order       string
		Title       string
		Icon_or_url string
	}
	ids := strconv.FormatInt(menuids[0], 10)
	for i := 1; i < len(menuids); i++ {
		ids += ","
		ids += strconv.FormatInt(menuids[i], 10)
	}
	if err := model.DBSlaveRand().Select(&menuinfo, "SELECT * FROM t_base_menu WHERE id IN ("+ids+")"); err != nil {
		panic(err)
	}
	for _, v := range menuinfo {
		if v.Parent_id == 0 {
			menumap[v.Id] = &MenuL1{
				Title:   v.Title,
				Icon:    v.Icon_or_url,
				Submenu: []MenuL2{},
			}
		}
	}
	for _, v := range menuinfo {
		if v.Parent_id != 0 {
			if elem, ok := menumap[v.Parent_id]; ok {
				elem.Submenu = append(elem.Submenu, MenuL2{
					Title: v.Title,
					Url:   v.Icon_or_url,
				})
			}
		}
	}
	return
}

func getMenuList(menumap map[int64]*MenuL1) (menu []MenuL1) {
	var keys []int64
	for k := range menumap {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
	for _, k := range keys {
		menu = append(menu, *menumap[k])
	}
	return
}
